package com.hobobe.tiercel.server;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.ChannelGroupFuture;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.Delimiters;
import org.jboss.netty.handler.codec.string.StringDecoder;
import org.jboss.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hobobe.tiercel.XLServerEncoder;
import com.hobobe.tiercel.server.handler.ServerHandler;

/**
 * Tiercel服务
 * @author wjs
 *
 */
public class TiercelServer {
	
	public static final Logger logger=LoggerFactory.getLogger(TiercelServer.class);
	
	public int port =8081;
	public static final ChannelGroup allChannels=new DefaultChannelGroup("TiercelServer");
	private static final ServerBootstrap serverBootstrap=new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
	    
	public void init(){
		
	}
	
	public void start(){
		 /**
         * 采用默认ChannelPipeline管道
         * 这意味着同一个ServerHandler实例将被多个Channel通道共享
         * 这种方式对于ServerHandler中无有状态的成员变量是可以的，并且可以提高性能！
         */
        ChannelPipeline pipeline=serverBootstrap.getPipeline(); 
        /**
         * 解码器是基于文本行的协议，\r\n或者\n\r
         */
        pipeline.addLast("frameDecoder", new DelimiterBasedFrameDecoder(80, Delimiters.lineDelimiter()));
        pipeline.addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
        pipeline.addLast("encoder", new XLServerEncoder());
        pipeline.addLast("handler", new ServerHandler());
        
        serverBootstrap.setOption("child.tcpNoDelay", true); //注意child前缀
        serverBootstrap.setOption("child.keepAlive", true); //注意child前缀
        
        /**
         * ServerBootstrap对象的bind方法返回了一个绑定了本地地址的服务端Channel通道对象
         */
        Channel channel=serverBootstrap.bind(new InetSocketAddress(port));
        allChannels.add(channel);
        logger.info("tiercel server is started on port "+port);
       
	}
	
	public void shutdown() {
		try {
            /**
             * 主动关闭服务器
             */
            ChannelGroupFuture future=allChannels.close();
            future.awaitUninterruptibly();//阻塞，直到服务器关闭
            //serverBootstrap.releaseExternalResources();
        } catch (Exception e) {
            logger.error("tiercel server shutdown error,",e);
        }finally{
            logger.info("tiercel server is shutdown on port "+port);
            System.exit(1);
        }
	}
}
